#include "Device.hpp"
#include "DeviceSpecInfo.hpp"
#include "ConnMgr.hpp"
#include "Message.hpp"
#include "IncomingPacket.hpp"

#include <boost/thread.hpp>

namespace kieper {
    using std::string;
    using boost::mutex;
    using boost::condition_variable;
    using boost::unique_lock;
    
    Device::Device(uint16_t id, string desc, ConnMgr* connMgr, DeviceSpecInfo* deviceInfo) :
        id_(id), desc_(desc), connMgr_(connMgr), deviceInfo_(deviceInfo) {}
    
    Device::~Device() {}

    IncomingPacketPtr Device::sendSyncMsg(const Message& message) {
        mutex mtx;
        condition_variable condition;
        
        unique_lock<mutex> lock(mtx);
        
        message.getPacket().setDeviceId(id_);
        connMgr_->send(*this, message);

        uint32_t packetId = message.getPacket().getPacketId();
        connMgr_->putCondition(packetId, &condition);
        connMgr_->putMutex(packetId, &mtx);

        while (!connMgr_->responseArrived(message.getPacket().getPacketId())) {
            condition.wait(lock);
        }
        return connMgr_->getResponse(message.getPacket().getPacketId());
    }

    const DeviceSpecInfo* Device::getDeviceInfo() const {
        return deviceInfo_.get();
    }
}
